package view;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.RemoteException;
import java.util.ArrayList;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import model.BuyOrder;
import model.Order;
import server.Server;
import client.Client;

public class UserOrderPanel extends JPanel {
	private static final long serialVersionUID = 472792468507799994L;
	
	private ArrayList<Order> orders;
	private JList orderList;
	private DefaultListModel orderListModel;
	
	private JLabel reqQuantity;
	private JLabel reqPrice;
	private JLabel reqStock;
	private JLabel orderType;
	private JButton cancel;
	
	private Server server;
	private Client client;

	public UserOrderPanel() {
		// create and add the required listeners 
		orderType = new JLabel();
		reqStock = new JLabel();
		reqQuantity = new JLabel();
		reqPrice = new JLabel();
		cancel = new JButton("cancel order");
		cancel.addActionListener(new CancelOrderListener());
		orderListModel = new DefaultListModel();
		orderList = new JList(orderListModel);
		orderList.addListSelectionListener(new OrderSelectedListener());
		
		setLayout(new BorderLayout());
		add(new JScrollPane(orderList), BorderLayout.WEST);
		JPanel p = new JPanel(new GridBagLayout());
		
		GridBagConstraints c = new GridBagConstraints();
		c.fill = GridBagConstraints.HORIZONTAL;
		c.insets = new Insets(5, 5, 5, 5);
		c.weightx = 0.5;
		c.gridy = 0;

		c.gridy++;
		p.add(new JLabel("Order Type"), c);
		p.add(orderType, c);
		
		c.gridy++;
		p.add(new JLabel("Req. Stock"), c);
		p.add(reqStock, c);

		c.gridy++;
		p.add(new JLabel("Req. Price"), c);
		p.add(reqPrice, c);

		c.gridy++;
		p.add(new JLabel("Req. Quantity"), c);
		p.add(reqQuantity, c);

		c.gridy++;
		c.gridx = 1;
		p.add(cancel, c);

		add(p, BorderLayout.CENTER);
	}
	
	/**
	 * Update the view to show the data
	 * @param s
	 * 		The server object
	 * @param c
	 * 		The client object
	 * @throws RemoteException
	 */
	public void populate(Server server, Client client) throws RemoteException {
		// we dont want an older version of the object
		this.server = server;
		this.client = client;
		
		orders = server.getUserOrders(client);
		orderListModel.clear();
		for (Order o : orders) {
			orderListModel.addElement(o.getTransactionId());
		}
		if(!orderListModel.isEmpty()) {
			orderList.setSelectedIndex(0);
		}
	}
	
	/** Handles the selection of an order **/
	class OrderSelectedListener implements ListSelectionListener {

		public void valueChanged(ListSelectionEvent arg0) {
			// get the index
			int i = orderList.getSelectedIndex();
			// means there was actually an item
			if (i >= 0) {
				Order o = orders.get(i);
				// which type is it?
				orderType.setText((o instanceof BuyOrder) ? "Buy" : "Sell");
				// update the labels
				reqStock.setText(o.getStockName());
				reqPrice.setText(String.valueOf(o.getPrice()));
				reqQuantity.setText(String.valueOf(o.getNumber()));
			} else {
				orderType.setText("");
				reqStock.setText("");
				reqPrice.setText("");
				reqQuantity.setText("");
			}
		}
	}
	
	/** Handles cancelling an order **/
	class CancelOrderListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			try {
				// get the index
				int i = orderList.getSelectedIndex();
				// means there was actually an item
				if (i >= 0) {
					Order o = orders.get(i);
					// check what type it was and act accordingly
					if (o instanceof BuyOrder) {
						server.cancelBuy(client, o.getTransactionId());
					} else {
						server.cancelSell(client, o.getTransactionId());
					}
					// remove the order
					orderListModel.remove(i);
					orders.remove(i);
				}
			} catch (Exception e1) {
				JOptionPane.showMessageDialog(UserOrderPanel.this,
						"failed to cancel order: " + e1.getMessage(), "failed",
						JOptionPane.ERROR_MESSAGE);
			}
		}
		
	}
}
